﻿#pragma once
#include<iostream>
#include<string>
#include<vector>
#include<assert.h>
using namespace std;
namespace jz {
	template<class T>
	class vector {
	public:
		typedef T* iterator;
		typedef const T* const_iterator;
		vector()
		{
		}
		size_t capacity()
		{
			return _end_of_storage - _start;
		}
		/*vector(vector<T>& v)
		{
			_start = new T[v.capacity()];
			memcpy(_start, v._start, (v.size()) * sizeof(T));
			_finish = _start + v.size();
			_end_of_storage = _start + v.capacity();
		}*/
		/*vector(const vector<T>& v)
		{
			_start = new T[v.capacity()];
			memcpy(_start, v._start, (v.size()) * sizeof(T));
			_finish = _start + v.size();
			_end_of_storage = _start + v.capacity();
		}*/
		vector(const vector<T>& v)
		{
			reserve(v.capacity());
			for (const auto& x : v)
			{
				push_back(x);
			}
		}
			template<class typeiterator>
			vector(typeiterator first, typeiterator last)
			{
				while (first != last)
				{
					push_back(*first);
					++first;
				}
			}
		vector(size_t n, const T& val = T())
		{
			resize(n, val);
		}
		vector(int n, const T& val = T())
		{
			resize(n, val);
		}


		~vector()
		{
			if (_start)
			{
				delete[] _start;
				_start = _finish = _end_of_storage = nullptr;
			}
		}
		void prinf_vector(const vector n)
		{
			for (auto v : n)
			{
				cout << v << " ";
			}
			cout << endl;
		}
		void reserve(size_t  n)
		{
			size_t old = size();
			if (n >= capacity())
			{
				T* tem = new T[n];
				if (_start)
				{
					for (size_t i = 0; i < size(); i++)
					{
						tem[i] = _start[i];
					}
					delete[] _start;
				}
				this->_start = tem;
				this->_finish = _start + old;
				this->_end_of_storage = _start + n;
			}
		}
		void resize(size_t n, const T val = T())
		{
			if (n > size())
			{
				reserve(n);
				while (_finish != _start + n)
				{
					*_finish = val;
					_finish++;
				}
			}
			else {
				_finish = _start + n;
			}

		}
		iterator insert(iterator pos, const T& val)
		{
			assert(pos >= _start && pos < _finish);
			size_t mark = pos - _start;
			if (_finish == _end_of_storage)
			{
				size_t newcapacity = (capacity() == 0 ? 4 : capacity() * 2);
				reserve(newcapacity);
			}
			pos = _start + mark;
			iterator x = _finish;
			while (x > pos)
			{
				*x = *(x - 1);
				x--;
			}
			*pos = val;
			_finish++;
			return pos;
		}
		iterator erase(iterator pos)
		{
			assert(pos >= _start);
			assert(pos < _finish);
			vector<T>::iterator v = pos + 1;
			while (v < _finish)
			{
				*(v - 1) = *v;
				++v;
			}
			--_finish;
			return pos;
		}
		void push_back(T n)
		{
			if (_finish == _end_of_storage)
			{
				size_t newcapacity = (capacity() == 0 ? 4 : capacity() * 2);
				reserve(newcapacity);
			}
			*_finish = n;
			_finish++;
		}
		void pop_back()
		{
			assert(size() > 0);
			_finish--;
		}

		size_t size()
		{
			return _finish - _start;
		}
		iterator begin()
		{
			return _start;
		}
		iterator end()
		{
			return _finish;
		}
		const_iterator begin() const
		{
			return _start;
		}
		const_iterator end() const
		{
			return _finish;
		}
		T& operator[](size_t  n)
		{
			assert(n < size());

			return *(_start + n);
		}
		const T& operator[](size_t  n)  const
		{
			assert(n < size());
			return *(_start + n);
		}
		void swap(vector<T>& n)
		{
			std::swap(_start, n._start);
			std::swap(_finish, n._finish);
			std::swap(_end_of_storage, n._end_of_storage);
		}
		vector<T>& operator=(vector<T> n)
		{
			swap(n);
			return *this;
		}
	private:
		iterator _start = nullptr;
		iterator _finish = nullptr;
		iterator _end_of_storage = nullptr;
	};
	//void test()
	//{
	//	vector<int> n;
	//	n.push_back(1);
	//	n.push_back(2);
	//	n.push_back(3);
	//	n.push_back(4);
	//	n.push_back(5);
	//	for (int i = 0; i < n.size(); i++)
	//	{
	//		cout << n[i] << " ";
	//	}
	//	cout << endl;
	//	auto it = n.begin();
	//	while (it != n.end())
	//	{
	//		cout << *it << " ";
	//		it++;
	//	}
	//	cout << endl;
	//	n.insert(n.begin(),100);
	//	/*n.resize(100,9);*/
	//	for (auto v : n)
	//	{
	//		cout << v << " ";
	//	}
	//	cout << endl;
	//	/*n.prinf_vector(n);*/
	//}
	/*void test2()
	{
		vector<int> v1;
		v1.push_back(1);
		v1.push_back(2);
		v1.push_back(2);
		v1.push_back(3);
		for (auto v : v1)
		{
			cout << v << " ";
		}
		cout << endl;
		vector<int> v2;
		v2.push_back(2);
		v2.push_back(2);
		v2.push_back(2);
		v2.push_back(2);

		v2.push_back(2);
		v2 = v1;
		for (auto v : v2)
		{
			cout << v << " ";
		}
		cout << endl;
	}*/
	//void test3()
	//{
	//	vector<int> x;
	//	x.push_back(1);
	//	x.push_back(2);
	//	x.push_back(3);
	//	x.push_back(4);
	//	for (auto v : x)
	//	{
	//		cout << v << " ";
	//	}
	//	cout << endl;
	//	x.erase(x.begin()+1);
	//	for (auto v : x)
	//	{
	//		cout << v << " ";
	//	}
	//	cout << endl;


	//}
	/*void test4()
	{
		vector<int> v;
		v.push_back(1);
		v.push_back(2);
		v.push_back(3);
		v.push_back(4);
		v.push_back(5);
		v.push_back(6);
		for (auto v : v)
		{
			cout << v << " ";
		}
		cout << endl;
		vector<int>::iterator x = v.begin();
		while (x < v.end())
		{
			if (*x % 2 == 0)
			{
				x = v.erase(x);
			}
			x++;
		}
		for (auto v : v)
		{
			cout << v << " ";
		}
		cout << endl;

	}*/
	void test5()
	{
		vector<string> x;
		x.push_back("1111");
		x.push_back("1111");
		x.push_back("1111");
		x.push_back("1111");
		x.push_back("1111");
		x.push_back("1111");
		x.push_back("1111");
		x.push_back("1111");
		vector<int> v(10, 5);
		for (auto v : v)
		{
			cout << v << " ";
		}
		cout << endl;
	}
	
};
